using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Decav.Gatsb.Mobile;
using Decav.Gatsb.Application.Configuration;

namespace Decav.Gatsb.Application.CommandWorkflow
{
    [DisplayName("Parse SMS Message")]
	public partial class ParseMessageActivity: Activity
	{
		public ParseMessageActivity()
		{
			InitializeComponent();
		}

        public static DependencyProperty InputMessageProperty = DependencyProperty.Register(
            "InputMessage", typeof(MobileMessage), typeof(ParseMessageActivity));

        /// <summary>
        /// Gets the message that is input to be parsed.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        public MobileMessage InputMessage
        {
            get { return (MobileMessage)GetValue(InputMessageProperty); }
            set { SetValue(InputMessageProperty, value); }
        }

        public static DependencyProperty CommandTextProperty = DependencyProperty.Register(
            "CommandText", typeof(string), typeof(ParseMessageActivity));

        /// <summary>
        /// Gets the string that defines the command that was parsed, without the prefix.
        /// </summary>
        public string CommandText
        {
            get { return (string)GetValue(CommandTextProperty); }
            set { SetValue(CommandTextProperty, value); }
        }

        /// <summary>
        /// The dependency property that gets or sets the type of command to execute.
        /// </summary>
        public static DependencyProperty CommandTypeProperty = DependencyProperty.Register(
            "CommandType", typeof(WorkflowCommandType), typeof(ParseMessageActivity));

        /// <summary>
        /// Gets or sets the type of command to execute.
        /// </summary>
        public WorkflowCommandType CommandType
        {
            get { return (WorkflowCommandType)GetValue(CommandTypeProperty); }
            set { SetValue(CommandTypeProperty, value); }
        }

        /// <summary>
        /// The dependency property that gets or sets the full command text, including its prefix.
        /// </summary>
        public static DependencyProperty FullCommandTextProperty = DependencyProperty.Register(
            "FullCommandText", typeof(string), typeof(ParseMessageActivity));

        /// <summary>
        /// Gets or sets the full command text, including its prefix.
        /// </summary>
        public string FullCommandText
        {
            get { return (string)GetValue(FullCommandTextProperty); }
            set { SetValue(FullCommandTextProperty, value); }
        }
        
        
        

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            if (InputMessage == null)
                throw new ArgumentNullException("InputMessage");

            foreach (CommandConfiguration config in GatsbApplicationConfigurationSection.Current.Commands)
            {
                string[] prefixes = config.Prefixes.Split(new char[] {';' }, StringSplitOptions.RemoveEmptyEntries );

                string commandLessPrefix = null;
                if (FindCommand(prefixes, out commandLessPrefix))
                {
                    FullCommandText = GetFirstLine();
                    CommandText = commandLessPrefix;
                    CommandType = config.Name;
                    break;
                }
            }

            return ActivityExecutionStatus.Closed;
        }

        /// <summary>
        /// Finds a command in the <see cref="InputMessage"/>'s first line.
        /// </summary>
        /// <param name="commandPrefixes">The possible prefixes to use to parse this command.</param>
        /// <param name="innerText">The text after the command prefix.</param>
        /// <returns>True when a command is found, else false.</returns>
        private bool FindCommand(string[] commandPrefixes, out string innerText)
        {
            if (string.IsNullOrEmpty(InputMessage.Body))
            {
                innerText = null;
                return false;
            }

            string command = GetFirstLine();

            foreach (string prefix in commandPrefixes)
            {
                if (command.StartsWith(prefix))
                {
                    innerText = command.Substring(prefix.Length).Trim();
                    return true;
                }
            }

            innerText = null;
            return false;
        }

        /// <summary>
        /// Gets the first line of the <see cref="InputMessage"/> body.
        /// </summary>
        /// <returns>The first line of the body.</returns>
        private string GetFirstLine()
        {
            return MessageParser.GetFirstLine(InputMessage);
        }
	}
}
